﻿using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace zy_simu.Data
{
    public class DisplayPanel : ComponentBase
    {
        [Inject]
        protected DeviceSnap dev_snap { get; set; }

        public void Init()
        {
            disp_buf = new byte[dev_snap.disp_buff_size];
            if (dev_snap.dev_type == 2432601)
                title = $"DisplayPanel - whh{dev_snap.dev_type}";
            else if (dev_snap.dev_type == 2432602)
                title = $"DisplayPanel - MD{dev_snap.dev_type}";
            else if (dev_snap.dev_type == 2432603)
                title = $"DisplayPanel - GD6_{dev_snap.dev_type}";
            else
                title = $"DisplayPanel - AKM{dev_snap.dev_type}";
            kkey = mkey = 0;
        }
        // key related functions --------------------------------------------------------------------------------------------------
        public byte GetKey()
        {
            return (byte)(kkey | mkey);
        }
        public void Display(byte[] buff, uint[] k_state)
        {
            //led_icon_def
            disp_item_digital[0] = disp_item_digital[1] = disp_item_digital[2] = "";
            for (int i = 0; i < disp_buf.Length; i++)
                disp_buf[i] = buff[i];

            for (int i = 0; i < dev_snap.disp_digital_cnt; i++)
            {
                int j = 0;
                if(dev_snap.disp_panel == 6)
                    j = disp_item_digital.Length - i - 1; // 硬件是倒序的
                else
                    j = i + disp_item_digital.Length - dev_snap.disp_digital_cnt;
                foreach (LedCharCode code in led_char_codes)
                {
                    if (code.code == (disp_buf[i+ dev_snap.disp_item_d_start] & 0x7f))
                    {
                        disp_item_digital[j] = ((char)code.ch).ToString();
                        break;
                    }
                }
            }
            // display key states
            KeyStateString = "按键状态:";
            for (int i = 0; i < dev_snap.keys_def.Length; i++)
            {
                string str;
                if ((k_state[i] & 0x80000000) == 0)
                    str = string.Format("{0}: up", dev_snap.keys_def[i]);
                else if ((k_state[i] & 0x7fffffff) > 1000)
                    str = string.Format("{0}: keep-{1}", dev_snap.keys_def[i], (k_state[i] & 0x7fffffff));
                else
                    str = string.Format("{0}: down", dev_snap.keys_def[i]);
                KeyStateString += string.Format(" {0} |", str);
            }
            //macro_service.record_key(k_state);
            InvokeAsync(StateHasChanged);
        }
        public Dictionary<string, string> Snap()
        {
            Dictionary<string, string> dict = new Dictionary<string, string>();
            for (int i = 0; i < 8; i++)
            {
                int n = led_icons_map[i];
                if (dev_snap.led_icon_def[n, 1] == 0) // 没有这个灯
                    continue; 
                else if (GetLightState(n)) // 灯亮
                    dict[led_icons_name[i]] = "1";
                else // 灯灭
                    dict[led_icons_name[i]] = "0";
            }
            // 负号和小数点
            if (GetLightState(14))
                dict["小数点"] = "1";
            else
                dict["小数点"] = "0";
            if (GetLightState(15))
                dict["负号"] = "1";
            else
                dict["负号"] = "0";

            string digital = disp_item_digital[0] + disp_item_digital[1] + disp_item_digital[2];
            if(digital == $"{dev_snap.st.d_temp, 3}")
                dict["数显"] = "显示温度";
            else
                dict["数显"] = digital.Replace(' ', '/');  // "/"取代空格, 空格有可能会被后续裁剪掉

            return dict;
        }

        protected struct LedCharCode
        {
            public char ch;
            public byte code;

            public LedCharCode(char ch, byte code)
            {
                this.ch = ch;
                this.code = code;
            }
        };
        protected LedCharCode[] led_char_codes = {
                                          // MASK -------------- | HG FE DCBA |
            new LedCharCode('0', 0x3f),   // '0' --  ABCDEF   -- |    11 1111 | --
            new LedCharCode('1', 0x06),   // '1' --   BC      -- |        11  | --
            new LedCharCode('2', 0x5b),   // '2' --  AB DE G  -- |  1  1 1 11 | --
            new LedCharCode('3', 0x4f),   // '3' --  ABCD  G  -- |  1    1111 | --
            new LedCharCode('4', 0x66),   // '4' --   BC  FG  -- |  1 1   11  | --
            new LedCharCode('5', 0x6d),   // '5' --  A CD FG  -- |  1 1  11 1 | --
            new LedCharCode('6', 0x7d),   // '6' --  A CDEFG  -- |  1 11 11 1 | --
            new LedCharCode('7', 0x07),   // '7' --  ABC      -- |        111 | --
            new LedCharCode('8', 0x7f),   // '8' --  ABCDEFG  -- |  1 11 1111 | --
            new LedCharCode('9', 0x6f),   // '9' --  ABCD FG  -- |  1 1  1111 | --
            new LedCharCode('A', 0x77),   // 'A' --  ABC EFG  -- |  1 11  111 | --
            new LedCharCode('a', 0x77),   // 'A' --  ABC EFG  -- |  1 11  111 | --
            new LedCharCode('B', 0x7c),   // 'b' --    CDEFG  -- |  1 11 11   | --
            new LedCharCode('b', 0x7c),   // 'b' --    CDEFG  -- |  1 11 11   | --
            new LedCharCode('C', 0x39),   // 'C' --  A  DEF   -- |    11 1  1 | --
            new LedCharCode('c', 0x58),   // 'c' --     DE G  -- |  1  1 1    | --
            new LedCharCode('D', 0x5e),   // 'd' --   BCDE G  -- |  1  1 111  | --
            new LedCharCode('d', 0x5e),   // 'd' --   BCDE G  -- |  1  1 111  | --
            new LedCharCode('E', 0x79),   // 'E' --  A  DEFG  -- |  1 11 1  1 | --
            new LedCharCode('e', 0x79),   // 'E' --  A  DEFG  -- |  1 11 1  1 | --
            new LedCharCode('F', 0x71),   // 'F' --  A   EFG  -- |  1 11    1 | --
            new LedCharCode('f', 0x71),   // 'F' --  A   EFG  -- |  1 11    1 | --
            new LedCharCode('H', 0x76),   // 'H' --   BC EFG  -- |  1 11  11  | --
            new LedCharCode('i', 0x30),   // '1' --      EF   -- |    11      | --
            new LedCharCode('L', 0x38),   // 'L' --     DEF   -- |    11 1    | --
            new LedCharCode('n', 0x54),   // 'n' --    C E G  -- |  1  1  1   | --
            new LedCharCode('o', 0x5c),   // 'o' --    CDE G  -- |  1  1 11   | --
            new LedCharCode('P', 0x73),   // 'P' --  AB  EFG  -- |  1 11   11 | --
            new LedCharCode('r', 0x50),   // 'r' --      E G  -- |  1  1      | --
            new LedCharCode('S', 0x6d),   // 's' --  A C  FG  -- |  1 1   1 1 | --
            new LedCharCode('s', 0x6d),   // 's' --  A C  FG  -- |  1 1   1 1 | --
            new LedCharCode('t', 0x78),   // 't' --     DEFG  -- |  1 11 1    | --
            new LedCharCode('-', 0x40),   // '-' --        G  -- |  1         | --
            new LedCharCode(' ', 0x00),   // ' ' --        G  -- |            | --
            new LedCharCode('/', 0x52),   // '/' --   B  E G  -- |  1  1   1  | --
            new LedCharCode('Z', 0xff),   // 'Z' --  ABCDEFGH -- | 11 11 1111 | --
            new LedCharCode('U', 0x3e),   // '0' --   BCDEF   -- |    11 111  | --
            new LedCharCode('u', 0x3e),   // '0' --   BCDEF   -- |    11 111  | --
            new LedCharCode('\'',0x02),   // ''' --   B       -- |        1   | --
            new LedCharCode(',', 0x04),   // ',' --    C      -- |       1    | --
        };
        protected string title = "";
        protected int[] led_icons_map = {};
        protected string[] led_icons_name = {};
        protected string[] led_icons_class = {};
        protected byte mkey = 0;                // 鼠标button产生的模拟key
        protected byte kkey = 0;                // 键盘产生的模拟key
        protected string KeyStateString = " ";  // 实时key状态表述
        protected byte[] disp_buf = { };
        protected string[] disp_item_digital = { };

        // 是否点亮idx标识的图标
        protected bool GetLightState(int idx)
        {
            return ((disp_buf[dev_snap.led_icon_def[idx, 0]] & dev_snap.led_icon_def[idx, 1]) != 0);
        }
        // 鼠标button产生的模拟key
        protected void OnMouseDown(int i)
        {
            if (i >= 0 && i < dev_snap.keys_def.Length)
                mkey |= (byte)(1 << i);
        }
        protected void OnMouseUp(int i)
        {
            if (i >= 0 && i < dev_snap.keys_def.Length)
                mkey &= (byte)~(1 << i);
        }
        // 键盘产生的模拟key, 含快捷键
        protected void HandleKeyUpDown(KeyboardEventArgs e)
        {
            int i = 0;
            for (; i < dev_snap.keys_def.Length; i++)
            {
                // general hot key - set, plus, minus
                if (e.Key == "s" && "SET" == dev_snap.keys_def[i]) break; // set key pressed
                if (e.Key == "f" && "FUNC" == dev_snap.keys_def[i]) break; // func key pressed
                if (e.Key == "w" && "SWITCH" == dev_snap.keys_def[i]) break; // switch key pressed
                if ((e.Key == "=" || e.Key == "+") && "PLUS" == dev_snap.keys_def[i]) break; // plus key pressed
                if ((e.Key == "-" && "MINUS" == dev_snap.keys_def[i])) break; // minus key pressed
            }
            if (i == dev_snap.keys_def.Length) // 不是s/f/w/=/-; 看看是不是1/2/3/4等数字快捷键
                i = (sbyte)(e.Key.First() - 0x30);
            if (i >= dev_snap.keys_def.Length) // 都不是
                return;
            if (e.Type == "keydown")
                kkey |= (byte)(1 << i);
            else if (e.Type == "keyup")
                kkey &= (byte)~(1 << i);
        }

        protected string GetButtonBKColor(int i)
        {
            if (i < dev_snap.keys_def.Length)
                return "background-color:lightgray";
            else
                return "background-color:black";
        }
        protected string GetButtonIcon(int i)
        {
            if (i < dev_snap.keys_def.Length)
            {
                string ret = dev_snap.button_icons.GetValueOrDefault(dev_snap.keys_def[i], "");
                if (ret != "") return ret;
            }
            i %= 10; // 没有指定图标，返回简单0-9数字图标
            return $"fas fa-{i}";
        }
        protected string GetIconClass(int i)
        {
            return led_icons_class[i];
        }
        protected string GetIconColor(int i)
        {
            i = led_icons_map[i];
            if (dev_snap.led_icon_def[i, 1] == 0)
                return "color:black";
            else if (GetLightState(i))
                return "color:red";
            else
                return "color: dimgrey";
        }
        protected string GetLightColor(int i, string color)
        {
            i = led_icons_map[i];
            if (dev_snap.led_icon_def[i, 1] == 0)
                return "background-color:black";
            else if (GetLightState(i))
                return $"background-color:{color}";
            else
                return "background-color: dimgrey";
        }
    }
}
